feat: optimize bundle by replacing react-syntax-highlighter with pris…#5599
feat: optimize bundle by replacing react-syntax-highlighter with pris…#5599patilpratik1905 wants to merge 9 commits into
Conversation
…m-react-renderer - Add bundle analyzer setup and documentation - Create lightweight shim for react-syntax-highlighter - Migrate CodeBlock to use prism-react-renderer directly - Configure webpack alias to redirect imports to the shim - Reduce bundle size by removing unused Refractor language definitions �
✅ Deploy Preview for asyncapi-website ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe PR replaces code highlighting with ChangesPrism highlighting and build wiring
Tool-building refactor
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant CodeBlock
participant Highlight
participant CodeLine
CodeBlock->>Highlight: pass normalized language and code content
Highlight->>CodeLine: provide tokenized lines and line props
CodeLine-->>CodeBlock: render styled lines, numbers, and tokens
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
⚡️ Lighthouse report for the changes in this PR:
Lighthouse ran on https://deploy-preview-5599--asyncapi-website.netlify.app/ |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@next.config.mjs`:
- Around line 12-19: The static import of the bundle analyzer in next.config.mjs
can crash production when devDependencies are omitted, so change the config to
load `@next/bundle-analyzer` only when ANALYZE is true. Update the next.config.mjs
export to use an async default function and apply a conditional dynamic import
around the existing withBundleAnalyzer setup, keeping the rest of the Next.js
config unchanged. Ensure the analyzer wrapper is only created in the ANALYZE
path and otherwise returns the plain config.
In `@package.json`:
- Around line 10-12: The analyze:server and analyze:browser scripts in
package.json are misleading because next.config.mjs only checks ANALYZE and
ignores BUNDLE_ANALYZE, so both scripts currently behave the same. Remove the
unused BUNDLE_ANALYZE assignments from those script entries, or consolidate them
into one analyze script if no separate server/browser reports are actually
produced, and keep the script names aligned with the behavior in next.config.mjs
and npm run build.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 79335269-84a6-49c2-b240-20dced03182b
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (4)
components/editor/CodeBlock.tsxcomponents/shims/react-syntax-highlighter-shim.tsxnext.config.mjspackage.json
…olving this lint error and not performance
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
components/editor/CodeBlock.tsx (1)
173-173: 🎯 Functional Correctness | 🔵 TrivialVerify Prism language normalization before shipping
CodeBlockProps.languageis a genericstring, andHighlightreceivescodeLanguage as anywithout validation or normalization. The codebase contains Markdown/MDX files using non-Prism language identifiers (e.g.,mermaid,asyncapi,generator-cli) that bypass TypeScript checks due to theas anycast.While
prism-react-renderertypically defaults unknown languages to plain text, this leaves no compile-time safety or runtime handling for unsupported aliases. Add a normalization utility to map common aliases to valid Prism identifiers (e.g.,yml→yaml,sh→bash) and implement a fallback toplaintextfor unsupported values.// Example normalization const normalizeLanguage = (lang?: string): string => { const map: Record<string, string> = { yml: 'yaml', sh: 'bash', js: 'javascript', ts: 'typescript' }; if (!lang) return 'plaintext'; const normalized = map[lang.toLowerCase()] || lang.toLowerCase(); // Validate against Prism languages list or fallback to 'plaintext' return supportedLanguages.includes(normalized) ? normalized : 'plaintext'; };Update line 149 to use
normalizeLanguage(currentBlock?.language || language)instead of direct usage.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/editor/CodeBlock.tsx` at line 173, The CodeBlock highlighting path uses a raw string cast to any, so unsupported or aliased languages can slip through without validation. Add a normalization helper in CodeBlock.tsx to map common aliases like yml to yaml and sh to bash, then verify the result against Prism-supported languages. Use the normalized value when computing the language for Highlight and fall back to plaintext for unknown or missing values instead of passing codeLanguage as any.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@components/editor/CodeBlock.tsx`:
- Around line 176-177: Fix the Prettier/ESLint formatting violation in the
className template literal inside CodeBlock by reformatting the conditional
expression and wrapping so it matches the project’s Prettier style. Keep the
same logic in CodeBlock, but adjust the multiline template literal formatting
around showLineNumbers, textSizeClassName, and codeClassName so CI passes.
---
Nitpick comments:
In `@components/editor/CodeBlock.tsx`:
- Line 173: The CodeBlock highlighting path uses a raw string cast to any, so
unsupported or aliased languages can slip through without validation. Add a
normalization helper in CodeBlock.tsx to map common aliases like yml to yaml and
sh to bash, then verify the result against Prism-supported languages. Use the
normalized value when computing the language for Highlight and fall back to
plaintext for unknown or missing values instead of passing codeLanguage as any.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5f794c98-fef8-42a6-a598-65adc8575382
📒 Files selected for processing (3)
components/editor/CodeBlock.tsxcomponents/icons/Book.tsxcomponents/shims/react-syntax-highlighter-shim.tsx
✅ Files skipped from review due to trivial changes (1)
- components/icons/Book.tsx
There was a problem hiding this comment.
-
Have you checked Sonar? It reports 9 issues.
-
CodeRabbit also has some suggestions.
-
The pipeline is failing for this PR.
-
Please be transparent about the sources of evidence you're using to validate these performance metrics so that we can re-verify them on our end as well. Currently, it's just an image (your PR evidence) claiming that the performance has increased. Please provide the link/steps so that we can verify the results and analyze them ourselves.
-
Also, did you check the Lighthouse report already attached to this PR? It seems to have been overlooked.
If you compare that report, the performance improvement is only marginal, from 49 to 55.
Reference:
Could you explain the reason for this discrepancy? You mentioned that the performance had improved significantly, but that isn't reflected in the Lighthouse report.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #5599 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 23 23
Lines 931 931
Branches 180 179 -1
=========================================
Hits 931 931 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
components/shims/react-syntax-highlighter-shim.tsx (1)
7-60: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRun Prettier to clear the reported formatting errors.
Static analysis flags numerous
prettier/prettierviolations across this theme object (trailing commas at Lines 7, 12, 16, …, and array reflow at 27-37). Please run the formatter to resolve them.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/shims/react-syntax-highlighter-shim.tsx` around lines 7 - 60, Run Prettier on the theme object in the react syntax highlighter shim, including the style entries and multiline types array, to normalize trailing commas, spacing, and array wrapping without changing the theme values.Source: Linters/SAST tools
next.config.mjs (1)
74-86: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueName the async config function (SonarCloud).
The conditional dynamic import correctly resolves the earlier
MODULE_NOT_FOUNDconcern. As a minor follow-up, SonarCloud flags the anonymous async default export; naming it aids stack traces.♻️ Optional
-export default async function () { +export default async function buildNextConfig() {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@next.config.mjs` around lines 74 - 86, Name the anonymous async default-exported configuration function, using a descriptive identifier such as nextConfig, while preserving its existing dynamic import and returned configuration behavior.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@components/editor/CodeBlock.tsx`:
- Around line 355-385: Run the repository formatting command (npm run prettier
or the equivalent format script) across CodeBlock.tsx and the affected files,
ensuring Prettier fixes trailing commas, JSX quote style, and unnecessarily
split expressions. Verify the dedicated lint job passes afterward.
- Around line 374-376: Update the `output` live region in `CodeBlock` so that
when `showIsCopied` is true it announces a copy-success confirmation such as
“Copied to clipboard” instead of the action label “Copy to clipboard”; keep it
empty when false.
- Around line 39-84: Update SUPPORTED_LANGUAGES to include the bundled Prism
languages swift, kotlin, js-extras, and rust, and replace the invalid css-extr
entry with the correct Prism language identifier. Verify normalizeLanguage now
preserves these supported fence languages instead of falling back to plaintext.
In `@components/shims/react-syntax-highlighter-shim.tsx`:
- Around line 40-59: The syntax highlighting style list contains duplicate
definitions for keyword, tag, and selector, with the later rule overriding
earlier colors. Update the style configuration in the React syntax highlighter
shim to consolidate each token type into one entry, preserving the intended
colors and removing the redundant overlapping definitions.
---
Nitpick comments:
In `@components/shims/react-syntax-highlighter-shim.tsx`:
- Around line 7-60: Run Prettier on the theme object in the react syntax
highlighter shim, including the style entries and multiline types array, to
normalize trailing commas, spacing, and array wrapping without changing the
theme values.
In `@next.config.mjs`:
- Around line 74-86: Name the anonymous async default-exported configuration
function, using a descriptive identifier such as nextConfig, while preserving
its existing dynamic import and returned configuration behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 452451a8-b0d9-4b8e-9849-701302ef21d9
📒 Files selected for processing (3)
components/editor/CodeBlock.tsxcomponents/shims/react-syntax-highlighter-shim.tsxnext.config.mjs
| const SUPPORTED_LANGUAGES = new Set<string>([ | ||
| 'markup', | ||
| 'bash', | ||
| 'clike', | ||
| 'c', | ||
| 'cpp', | ||
| 'css', | ||
| 'javascript', | ||
| 'jsx', | ||
| 'coffeescript', | ||
| 'actionscript', | ||
| 'css-extr', | ||
| 'diff', | ||
| 'git', | ||
| 'go', | ||
| 'graphql', | ||
| 'handlebars', | ||
| 'json', | ||
| 'less', | ||
| 'makefile', | ||
| 'markdown', | ||
| 'objectivec', | ||
| 'ocaml', | ||
| 'python', | ||
| 'reason', | ||
| 'sass', | ||
| 'scss', | ||
| 'sql', | ||
| 'stylus', | ||
| 'tsx', | ||
| 'typescript', | ||
| 'wasm', | ||
| 'yaml', | ||
| 'plaintext', | ||
| 'ruby', | ||
| ]); | ||
|
|
||
| /** | ||
| * @description Normalizes a language string to a valid Prism identifier. | ||
| */ | ||
| function normalizeLanguage(lang?: string): Language { | ||
| if (!lang) return 'plaintext' as Language; | ||
| const lower = lang.toLowerCase(); | ||
| const mapped = LANGUAGE_ALIASES[lower] || lower; | ||
|
|
||
| return (SUPPORTED_LANGUAGES.has(mapped) ? mapped : 'plaintext') as Language; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
prism-react-renderer 2.4.1 default bundled prism languages list
💡 Result:
In prism-react-renderer version 2.4.1, the default bundled Prism languages are defined in the project's language generation configuration [1][2]. The languages explicitly included in the bundle are: * markup * jsx * tsx * swift * kotlin * objectivec * js-extras * reason * rust * graphql * yaml * go * cpp * markdown * python * json [3][2] Please note that this is a base set of languages, and because PrismJS identifies dependencies between languages, including one language may automatically include others required by it (for example, JSX includes JavaScript) [4]. If you require a language not on this list, you can add it by importing the specific definition from the main prismjs package [1][5].
Citations:
- 1: https://github.com/FormidableLabs/prism-react-renderer/tree/prism-react-renderer%402.4.1
- 2: https://raw.githubusercontent.com/FormidableLabs/prism-react-renderer/HEAD/packages/generate-prism-languages/index.ts
- 3: https://github.com/FormidableLabs/prism-react-renderer/compare/prism-react-renderer@2.3.1...prism-react-renderer@2.4.1
- 4: README.md link to supported langages broken (
includeLangs.js) FormidableLabs/prism-react-renderer#190 - 5: https://npmx.dev/package/prism-react-renderer/v/%5E2.4.1
🏁 Script executed:
ast-grep outline components/editor/CodeBlock.tsx --view expandedRepository: asyncapi/website
Length of output: 1237
🏁 Script executed:
sed -n '1,220p' components/editor/CodeBlock.tsxRepository: asyncapi/website
Length of output: 5061
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- outline ---'
ast-grep outline components/editor/CodeBlock.tsx --view expanded || true
echo '--- file ---'
sed -n '1,220p' components/editor/CodeBlock.tsxRepository: asyncapi/website
Length of output: 6173
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect related language aliases and package version.
rg -n "SUPPORTED_LANGUAGES|LANGUAGE_ALIASES|prism-react-renderer" components/editor -S
printf '\n--- package.json ---\n'
sed -n '1,220p' package.jsonRepository: asyncapi/website
Length of output: 6847
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- CodeBlock.tsx ---'
sed -n '1,220p' components/editor/CodeBlock.tsx
echo
echo '--- searches ---'
rg -n "css-extr|css-extras|js-extras|swift|kotlin|rust|ruby|plaintext|SUPPORTED_LANGUAGES|LANGUAGE_ALIASES" -S .Repository: asyncapi/website
Length of output: 20628
🌐 Web query:
prism-react-renderer 2.4.1 css-extras js-extras bundled grammar
💡 Result:
In prism-react-renderer version 2.4.1, the library includes a bundled, modified version of PrismJS that contains a core set of common language syntaxes rather than the full Prism library [1][2]. The specific languages included are not fixed to every available Prism grammar but are a curated, "arbitrary" subset intended to keep the bundle size manageable [2][3]. Regarding "css-extras" and "js-extras," these are not guaranteed to be part of the default bundled set in version 2.4.1 [3]. While the library bundles common languages like javascript, css, markup, and others [3], specialized grammar extensions like css-extras or js-extras often need to be added manually if they are not explicitly included in the default list [1][3]. If a language or a specific grammar extension is missing, you can add it by extending the bundled Prism instance [1][3]. The recommended approach is: 1. Import the Prism instance exported by prism-react-renderer [3][4]. 2. Set it to the global scope (if required by your build system) [1][4]. 3. Import the specific language definition from the prismjs/components/ directory [1][4]. Example: import { Highlight, Prism } from "prism-react-renderer"; (typeof global!== "undefined"? global: window).Prism = Prism; await import("prismjs/components/prism-css-extras"); // Adds the missing grammar [1][4] Note that some languages depend on others (e.g., javascript is often bundled or required by its extras), so ensuring the base language is loaded before adding extras is standard practice [1][5]. You can check the current "out of the box" supported languages by inspecting the library's internal configuration files if you require an exhaustive list for your specific installation [2][6].
Citations:
- 1: https://github.com/FormidableLabs/prism-react-renderer/tree/prism-react-renderer%402.4.1
- 2: https://www.npmjs.com/package/prism-react-renderer
- 3: https://fixdevs.com/blog/prism-react-renderer-not-working/
- 4: https://github.com/FormidableLabs/prism-react-renderer/blob/master/README.md
- 5: https://github.com/FormidableLabs/prism-react-renderer/compare/prism-react-renderer@2.3.1...prism-react-renderer@2.4.0
- 6: https://registry.npmjs.org/prism-react-renderer
🌐 Web query:
prism-react-renderer 2.4.1 packages generate-prism-languages index.ts languages list
💡 Result:
In prism-react-renderer version 2.4.1, the supported languages are defined in the packages/generate-prism-languages/index.ts file [1][2]. The library bundles a base set of language definitions, which are processed during build time [1][3]. The explicit top-level languages included in the bundle are [1]: - markup - jsx - tsx - swift - kotlin - objectivec - js-extras - reason - rust - graphql - yaml - go - cpp - markdown - json It is important to note that this list contains the top-level languages only [4]. PrismJS automatically includes any dependencies required by these languages (for example, including jsx also includes the base js grammar) [1][4]. If you need a language not included in this list, you can add support for it by importing the specific language definition from the main prismjs package in your own application code [2][5]. Example usage for adding an unsupported language: import { Highlight, Prism } from "prism-react-renderer"; (typeof global!== "undefined"? global: window).Prism = Prism; await import("prismjs/components/prism-applescript"); // Example for adding applescript [2]
Citations:
- 1: https://github.com/FormidableLabs/prism-react-renderer/blob/master/packages/generate-prism-languages/index.ts
- 2: https://github.com/FormidableLabs/prism-react-renderer/tree/prism-react-renderer%402.4.1
- 3: https://www.npmjs.com/package/prism-react-renderer
- 4: README.md link to supported langages broken (
includeLangs.js) FormidableLabs/prism-react-renderer#190 - 5: https://github.com/FormidableLabs/prism-react-renderer/blob/master/README.md
Align the Prism allowlist with bundled languages. prism-react-renderer 2.4.1 includes swift, kotlin, js-extras, and rust, but they’re missing here, so those fences fall back to plaintext. css-extr also doesn’t match a Prism language name.
🧰 Tools
🪛 ESLint
[error] 73-73: Delete ,
(prettier/prettier)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@components/editor/CodeBlock.tsx` around lines 39 - 84, Update
SUPPORTED_LANGUAGES to include the bundled Prism languages swift, kotlin,
js-extras, and rust, and replace the invalid css-extr entry with the correct
Prism language identifier. Verify normalizeLanguage now preserves these
supported fence languages instead of falling back to plaintext.
| { | ||
| types: ['atrule', 'keyword', 'attr-name', 'selector'], | ||
| style: { color: '#00a4db' }, | ||
| }, | ||
| { | ||
| types: ['function', 'deleted', 'tag'], | ||
| style: { color: '#d73a49' }, | ||
| }, | ||
| { | ||
| types: ['function-variable'], | ||
| style: { color: '#6f42c1' }, | ||
| }, | ||
| { | ||
| types: ['tag', 'selector', 'keyword'], | ||
| style: { color: '#00009f' }, | ||
| }, | ||
| { | ||
| types: ['property'], | ||
| style: { color: '#990055' }, | ||
| }, |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
prism-react-renderer themeToDict duplicate token types style merge order
💡 Result:
In prism-react-renderer, the themeToDict function processes the theme's styles array into a dictionary that maps token types to their corresponding style objects [1][2][3]. Regarding duplicate token types or overlapping definitions, the merge order is determined by the order in which the definitions appear in the theme's styles array [4]. Specifically, the library iterates through the styles array and applies them sequentially [4]. If multiple definitions in the array target the same token type, or if a token's class list matches multiple definitions, later entries in the array will effectively override or merge into the previous ones [4]. Because the implementation uses sequential application, later definitions have higher precedence [4]. If you are attempting to style tokens with finer granularity (e.g., distinguishing between specific combinations of classes vs. general tokens), the current theme system may not support it directly without explicit definitions for each specific combination, as it does not automatically resolve specificity hierarchies like CSS does [4]. If you find that the default precedence is not achieving the desired styling, you can manage this by ordering your styles array so that the most specific rules appear later, ensuring they override more general rules [4].
Citations:
- 1: https://www.npmjs.com/package/prism-react-renderer
- 2: https://github.com/FormidableLabs/prism-react-renderer/blob/master/README.md
- 3: https://blog.csdn.net/gitblog_00361/article/details/152003521
- 4: Finer grained theme type selectors FormidableLabs/prism-react-renderer#40
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the target file with line numbers
sed -n '1,140p' components/shims/react-syntax-highlighter-shim.tsx | cat -n
# Locate the theme usage and any related comments
rg -n "theme|styles|token|keyword|selector|tag|function-variable|deleted" components/shims/react-syntax-highlighter-shim.tsxRepository: asyncapi/website
Length of output: 5080
Remove the duplicate token definitions
keyword, tag, and selector are defined twice; the later #00009f rule wins, so the earlier colors never apply. Consolidate each token type to a single entry with the intended color.
🧰 Tools
🪛 ESLint
[error] 42-42: Delete ,
(prettier/prettier)
[error] 46-46: Delete ,
(prettier/prettier)
[error] 50-50: Delete ,
(prettier/prettier)
[error] 54-54: Delete ,
(prettier/prettier)
[error] 58-58: Delete ,
(prettier/prettier)
[error] 59-59: Delete ,
(prettier/prettier)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@components/shims/react-syntax-highlighter-shim.tsx` around lines 40 - 59, The
syntax highlighting style list contains duplicate definitions for keyword, tag,
and selector, with the later rule overriding earlier colors. Update the style
configuration in the React syntax highlighter shim to consolidate each token
type into one entry, preserving the intended colors and removing the redundant
overlapping definitions.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
scripts/build-tools.ts (1)
28-176: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winRun Prettier to fix formatting violations before merge.
The multi-line formatting introduced by this PR doesn't match the project's Prettier configuration. ESLint flags trailing commas (Lines 28, 69, 87, 114, 138), expressions that should be collapsed to one line (Lines 31-38, 41-43, 75-78, 90-92, 118-120, 127-129, 142-144, 150-167, 169-176), and missing blank lines (Lines 80-88). The logic itself is unchanged and correct — only the formatting needs adjustment.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/build-tools.ts` around lines 28 - 176, Run the project’s Prettier formatter on the affected build-tools code, especially the functions that call combineTools and combineAutomatedAndManualTools and the CLI invocation. Apply its configured trailing-comma, line-wrapping, expression-collapsing, and blank-line rules without changing behavior.Source: Linters/SAST tools
🧹 Nitpick comments (2)
scripts/tools/combine-tools.ts (2)
379-408: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsolidate duplicated ignored-output writing.
The two
ignoredOutputPathbranches differ only intotalIgnoredandignoredToolsvalues. Consolidating them eliminates ~15 lines of duplication and reduces the risk of the two branches drifting apart.♻️ Proposed refactor
- if (ignoredOutputPath && ignoredTools.length > 0) { - fs.writeFileSync( - ignoredOutputPath, - JSON.stringify( - { - description: - 'Auto-generated audit log of tools ignored during the last combine run.', - generatedAt: new Date().toISOString(), - totalIgnored: ignoredTools.length, - ignoredTools, - }, - null, - 2, - ), - ); - } else if (ignoredOutputPath && ignoredTools.length === 0) { - fs.writeFileSync( - ignoredOutputPath, - JSON.stringify( - { - description: - 'Auto-generated audit log of tools ignored during the last combine run.', - generatedAt: new Date().toISOString(), - totalIgnored: 0, - ignoredTools: [], - }, - null, - 2, - ), - ); + if (ignoredOutputPath) { + fs.writeFileSync( + ignoredOutputPath, + JSON.stringify( + { + description: + 'Auto-generated audit log of tools ignored during the last combine run.', + generatedAt: new Date().toISOString(), + totalIgnored: ignoredTools.length, + ignoredTools, + }, + null, + 2, + ), + ); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/tools/combine-tools.ts` around lines 379 - 408, Consolidate the two ignoredOutputPath branches in the combine-tools flow into one write operation guarded only by ignoredOutputPath. Build the audit object using ignoredTools.length and ignoredTools directly so both empty and non-empty cases share the same description, timestamp, formatting, and output behavior.
105-145: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUnify string and array language handling to reduce cognitive complexity.
The string branch (lines 105–124) and the array branch (lines 126–145) share near-identical search-or-create logic. Normalizing the string case to a single-element array at the top would eliminate the duplication and reduce
getFinalTool's cognitive complexity (SonarCloud flags 23, limit is 15).♻️ Proposed refactor
// there might be a tool without language if (toolObject.filters.language) { const languageArray: LanguageColorItem[] = []; - - if (typeof toolObject.filters.language === 'string') { - const languageSearch = await languageFuse.search( - toolObject.filters.language, - ); - - if (languageSearch.length) { - languageArray.push(languageSearch[0].item); - } else { - // adds a new language object in the Fuse list as well as in tool object - // so that it isn't missed out in the UI. - const languageObject = { - name: toolObject.filters.language, - color: 'bg-[`#57f281`]', - borderColor: 'border-[`#37f069`]', - }; - - languageList.push(languageObject); - languageArray.push(languageObject); - languageFuse = new Fuse(languageList, options); - } - } else { - for (const language of toolObject.filters.language) { - // eslint-disable-next-line no-await-in-loop - const languageSearch = await languageFuse.search(language); - - if (languageSearch.length > 0) { - languageArray.push(languageSearch[0].item); - } else { - // adds a new language object in the Fuse list as well as in tool object - // so that it isn't missed out in the UI. - const languageObject = { - name: language, - color: 'bg-[`#57f281`]', - borderColor: 'border-[`#37f069`]', - }; - - languageList.push(languageObject); - languageArray.push(languageObject); - languageFuse = new Fuse(languageList, options); - } - } + const languages = typeof toolObject.filters.language === 'string' + ? [toolObject.filters.language] + : toolObject.filters.language; + + for (const language of languages) { + // eslint-disable-next-line no-await-in-loop + const languageSearch = await languageFuse.search(language); + + if (languageSearch.length > 0) { + languageArray.push(languageSearch[0].item); + } else { + // adds a new language object in the Fuse list as well as in tool object + // so that it isn't missed out in the UI. + const languageObject = { + name: language, + color: 'bg-[`#57f281`]', + borderColor: 'border-[`#37f069`]', + }; + + languageList.push(languageObject); + languageArray.push(languageObject); + languageFuse = new Fuse(languageList, options); + } } finalObject.filters.language = languageArray; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/tools/combine-tools.ts` around lines 105 - 145, Refactor the language handling in getFinalTool by normalizing a string-valued toolObject.filters.language into a single-element array before iterating. Replace the separate string and array branches with one loop that performs the existing Fuse search-or-create logic for each language, preserving languageArray, languageList, and languageFuse updates.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@components/editor/CodeBlock.tsx`:
- Around line 262-285: Update the clipboard handling in the CodeBlock copy
method to catch navigator.clipboard.writeText rejection and fall back to the
existing textarea copy path. Extract the duplicated successful-copy state update
(setShowIsCopied and its timeout) into a reusable local helper, invoking it
after either copy method succeeds while preserving current behavior.
---
Outside diff comments:
In `@scripts/build-tools.ts`:
- Around line 28-176: Run the project’s Prettier formatter on the affected
build-tools code, especially the functions that call combineTools and
combineAutomatedAndManualTools and the CLI invocation. Apply its configured
trailing-comma, line-wrapping, expression-collapsing, and blank-line rules
without changing behavior.
---
Nitpick comments:
In `@scripts/tools/combine-tools.ts`:
- Around line 379-408: Consolidate the two ignoredOutputPath branches in the
combine-tools flow into one write operation guarded only by ignoredOutputPath.
Build the audit object using ignoredTools.length and ignoredTools directly so
both empty and non-empty cases share the same description, timestamp,
formatting, and output behavior.
- Around line 105-145: Refactor the language handling in getFinalTool by
normalizing a string-valued toolObject.filters.language into a single-element
array before iterating. Replace the separate string and array branches with one
loop that performs the existing Fuse search-or-create logic for each language,
preserving languageArray, languageList, and languageFuse updates.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ec876f6b-cd63-4c7f-aaf8-1466d0f81ce6
📒 Files selected for processing (3)
components/editor/CodeBlock.tsxscripts/build-tools.tsscripts/tools/combine-tools.ts
…Cloud top-level await issue" This reverts commit c136a7e.
|
|
Hi @princerajpoot20 I spent quite long time of week investigating the From my local testing (Lighthouse CI + Chrome DevTools), the changes show a noticeable improvement, especially in reducing Total Blocking Time (TBT). Desktop metrics improved significantly, while mobile also improved, although not shown by deployed vercel link as much as I'd hoped. Alongside that, I've been addressing SonarCloud and CodeRabbit feedback continuously. Every time I resolved one issue, another followup Sonar and CodeRabbit issues along with lint/style issue appeared in CI. While fixing those, a few extra files were added in this PR especially the build file which was just part of solving lint issue came in CI At the moment I'm stuck with a Git issue where the lint fixes are reflected locally, but Git isn't detecting any differences when I try to stage the files. I'm investigating that now. In the meantime, I'd really appreciate it if you could review the current code changes. Regarding the Lighthouse improvement concern, I think the smaller gain mainly comes from the mobile Lighthouse score, which is generally much stricter than desktop. I also have two follow-up optimization ideas that I'd prefer to keep as separate PRs:
Do you think these optimizations would be okay as two separate follow-up PRs? |
There was a problem hiding this comment.
Revert all the changes you've made to the tools workflow. The Sonar issue you're seeing will be resolved after that.
You don't need to fix that Sonar finding in the tools workflow ("Prefer top-level await over an async IIFE.").
We intentionally kept the implementation as it is, and the reason is explained here: #5225 (comment). Please take a look.
Since these are unrelated changes, just remove them, and Sonar will no longer report that issue.
Also PTAL #3186 (comment)
cc: @aeworxet
| const LANGUAGE_ALIASES: Record<string, string> = { | ||
| yml: 'yaml', | ||
| sh: 'bash', | ||
| shell: 'bash', | ||
| js: 'javascript', | ||
| ts: 'typescript', | ||
| py: 'python', | ||
| rb: 'ruby', | ||
| asyncapi: 'yaml', | ||
| 'generator-cli': 'bash', | ||
| mermaid: 'plaintext', | ||
| }; | ||
|
|
||
| const SUPPORTED_LANGUAGES = new Set<string>([ | ||
| 'markup', | ||
| 'bash', | ||
| 'clike', | ||
| 'c', | ||
| 'cpp', | ||
| 'css', | ||
| 'javascript', | ||
| 'jsx', | ||
| 'coffeescript', | ||
| 'actionscript', | ||
| 'css-extr', | ||
| 'diff', | ||
| 'git', | ||
| 'go', | ||
| 'graphql', | ||
| 'handlebars', |
There was a problem hiding this comment.
what is the need of these set values? seems like unrelated changes
| function resolveTag( | ||
| name: string, | ||
| list: LanguageColorItem[], | ||
| fuse: Fuse<LanguageColorItem>, | ||
| defaultColor: string, | ||
| defaultBorder: string, | ||
| ): { item: LanguageColorItem; fuse: Fuse<LanguageColorItem> } { | ||
| const results = fuse.search(name); | ||
|
|
||
| if (results.length > 0) { | ||
| return { item: results[0].item, fuse }; | ||
| } | ||
|
|
||
| const newItem: LanguageColorItem = { | ||
| name, | ||
| color: defaultColor, | ||
| borderColor: defaultBorder, | ||
| }; | ||
|
|
||
| list.push(newItem); | ||
|
|
||
| return { item: newItem, fuse: new Fuse(list, options) }; | ||
| } | ||
|
|
||
| async function resolveLanguageTags( | ||
| language: string | string[], | ||
| ): Promise<{ |
There was a problem hiding this comment.
again, what is the need of making changes in combine-tools file? it's a totally different workflow.
| @@ -57,18 +66,30 @@ async function buildTools( | |||
| toolsPath: string, | |||
| tagsPath: string, | |||
| ignorePath?: string, | |||
| ignoredOutputPath?: string | |||
| ignoredOutputPath?: string, | |||
There was a problem hiding this comment.
Again, there's no need to touch these files. They're unrelated to your changes. If you're getting a lint error, first check where it's coming from instead of running the lint command on the entire project. Otherwise, you'll end up making changes across the entire project that are unrelated to your work.
| "analyze": "cross-env NODE_OPTIONS=--max-old-space-size=16384 npm run build-scripts && cross-env NODE_OPTIONS=--max-old-space-size=16384 ANALYZE=true next build", | ||
| "analyze:server": "cross-env ANALYZE=true BUNDLE_ANALYZE=server npm run build", | ||
| "analyze:browser": "cross-env ANALYZE=true BUNDLE_ANALYZE=browser npm run build", |
There was a problem hiding this comment.
What purpose do these commands serve? If they're meant to analyze the bundle, do these commands need to be added to the project? If so, who is going to use them?



Summary of Previous Work
This PR is the result of a broader investigation into improving the website's Lighthouse performance and reducing the client-side bundle size.
The investigation started with understanding Lighthouse metrics, studying the optimization opportunities suggested by Lighthouse, and manually auditing the major pages across the website. Since Lighthouse analyzes one page at a time, each important route had to be evaluated individually to identify page-specific bottlenecks.
During this process, several optimizations were implemented, including:
One challenge throughout this work was obtaining reliable performance measurements, as Lighthouse scores varied significantly between Chrome DevTools and PageSpeed Insights, making it difficult to accurately evaluate the effectiveness of each change.
Although these improvements helped, they did not produce the significant performance gains that were expected. To better understand the remaining bottlenecks, I repeatedly analyzed the production bundle before and after each optimization.
Bundle Analysis
Before
After
This deeper investigation revealed that the primary bottleneck was not the usual frontend assets, but a large syntax-highlighting runtime.
The bundle analyzer consistently showed a large
highlight.js/libchunk. After tracing its dependency chain, I discovered that while most of the project had already migrated toprism-react-renderer, the Schyma package still internally depended onreact-syntax-highlighter, which itself relied on therefractorengine. Sincerefractorbundles hundreds of language grammars, it introduced a considerable amount of unnecessary JavaScript into the client bundle, even though Schyma only highlights JSON.I explored replacing Schyma's syntax-highlighting implementation directly, but those approaches introduced regressions and visual inconsistencies, particularly on the schema explorer pages:
/docs/reference/specification/v3.0.0-explorer/docs/reference/specification/v3.1.0-explorerTherefore, the objective became finding a solution that could eliminate the unnecessary runtime without modifying Schyma itself or affecting the existing user experience.
Solution
This PR eliminates the duplicate syntax-highlighting runtime introduced by Schyma by replacing its internal
react-syntax-highlighterdependency with a lightweight compatibility shim backed by the project's existingprism-react-renderer.Using webpack aliasing, Schyma's imports are transparently redirected to the shim at build time, requiring no changes to Schyma or any of its consumers. The shim exposes the same API that Schyma expects while internally delegating rendering to
prism-react-renderer, allowing Schyma to function exactly as before.This approach:
react-syntax-highlighter/refractorruntime from the client bundle.Improvements / Impact :
The performance improvements achieved in this PR primarily come from two major changes:
Replaced
react-syntax-highlighterwithprism-react-rendererprism-react-renderer, reducing the overall syntax-highlighting footprint while preserving the existing rendering and appearance.Eliminated Schyma's duplicate syntax-highlighting runtime
react-syntax-highlighterimports to the project's existingprism-react-rendererimplementation.react-syntax-highlighter/refractorruntime from the client bundle without modifying Schyma or affecting its functionality.Performance Improvements Metrics
Before
After
Future improvements
This PR delivers the most significant performance improvement identified during the Lighthouse optimization effort.
Related issue
Fixes: #3186
Summary by CodeRabbit
analyzescripts (server/browser) to inspect build output size.react-syntax-highlighter, addedreactflowandcross-env, and added@next/bundle-analyzer.